package datastructure.apply.maze;

import datastructure.SqStackClass;

import java.util.Arrays;

public class Maze {
    private byte[][] mazeArray;
    private SqStackClass<Diamond> stack;
    private Diamond endDiamond;

    public Maze(byte[][] mazeArray, Diamond startDiamond, Diamond endDiamond) {
        this.mazeArray = new byte[mazeArray.length][];
        for (int i = 0; i < mazeArray.length; i++)
            this.mazeArray[i] = Arrays.copyOf(mazeArray[i], mazeArray[i].length);
        stack = new SqStackClass<>();
        stack.push(startDiamond);
        this.mazeArray[stack.peek().getY()][stack.peek().getX()] = -1;
        this.endDiamond = endDiamond;
    }

    public byte[][] getMazeArray() {
        return mazeArray;
    }

    public void setMazeArray(byte[][] mazeArray) {
        this.mazeArray = mazeArray;
    }

    public SqStackClass<Diamond> getStack() {
        return stack;
    }

    public void setStack(SqStackClass<Diamond> stack) {
        this.stack = stack;
    }

    public Diamond getEndDiamond() {
        return endDiamond;
    }

    public void setEndDiamond(Diamond endDiamond) {
        this.endDiamond = endDiamond;
    }

    private Diamond directionToDiamond(Diamond diamond) {
        while (diamond.getDirection() >= -1 && diamond.getDirection() < 3) {
            diamond.setDirection(diamond.getDirection() + 1);
            int x = diamond.getX(), y = diamond.getY();
            switch (diamond.getDirection()) {
                case 0 -> --y;
                case 1 -> ++x;
                case 2 -> ++y;
                case 3 -> --x;
            }
            if (mazeArray[y][x] == 1)
                return new Diamond(x, y);
        }
        return null;
    }

    public boolean findPath() {
        while (!stack.empty()) {
            Diamond current = stack.peek();
            if (current.equals(endDiamond))
                return true;
            Diamond next = directionToDiamond(current);
            if (next == null) {
                mazeArray[current.getY()][current.getX()] = 1;
                stack.pop();
            } else {
                mazeArray[next.getY()][next.getX()] = -1;
                stack.push(next);
            }
        }
        return false;
    }
}


